package jinyilw.swing.rlaf.ui;

import jinyilw.swing.ComponentTools;
import jinyilw.swing.rlaf.theme.RThemeColor;
import jinyilw.swing.rlaf.ui.icon.RIconFactory;

import javax.swing.Icon;
import javax.swing.JComponent;
import javax.swing.JSlider;
import javax.swing.plaf.ComponentUI;
import javax.swing.plaf.basic.BasicSliderUI;
import java.awt.Composite;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Rectangle;

/**
 * @author Jinyi
 */
public class RSliderUI extends BasicSliderUI
{
	public static ComponentUI createUI(JComponent b)
	{
		return new RSliderUI((JSlider) b);
	}

	public RSliderUI(JSlider b)
	{
		super(b);
		b.setOpaque(false);
	}

	@Override
	public void update(Graphics g, JComponent c)
	{
		Composite composite = ComponentTools.applyEnableAlpha((Graphics2D) g, c,
				0.9f, 0.3f);
		paint(g, c);
		if (composite != null)
			((Graphics2D) g).setComposite(composite);
	}

	@Override
	public void paint(Graphics g, JComponent c)
	{
		recalculateIfInsetsChanged();
		recalculateIfOrientationChanged();
		Rectangle clip = g.getClipBounds();
		if (!clip.intersects(trackRect) && slider.getPaintTrack())
			calculateGeometry();
		if (slider.getPaintTrack() && clip.intersects(trackRect))
			paintTrack(g);
		if (slider.getPaintTicks() && clip.intersects(tickRect))
			paintTicks(g);
		if (slider.getPaintLabels() && clip.intersects(labelRect))
			paintLabels(g);
		if (clip.intersects(thumbRect))
			paintThumb(g);
	}

	@Override
	public void paintTrack(Graphics g)
	{
		Rectangle trackBounds = trackRect;
		g.setColor(RThemeColor.colorSet.borderColor);
		if (slider.getOrientation() == JSlider.HORIZONTAL)
		{
			int cy = (trackBounds.height / 2) - 2;
			int cw = trackBounds.width;
			g.translate(trackBounds.x, trackBounds.y + cy);
			g.drawRoundRect(0, 0, cw, 4, 2, 2);
			g.translate(-trackBounds.x, -(trackBounds.y + cy));
		} else
		{
			int cx = (trackBounds.width / 2) - 2;
			int ch = trackBounds.height;
			g.translate(trackBounds.x + cx, trackBounds.y);
			g.drawRoundRect(0, 0, 4, ch, 2, 2);
			g.translate(-(trackBounds.x + cx), -trackBounds.y);
		}
	}

	@Override
	public void paintTicks(Graphics g)
	{
		Rectangle tickBounds = tickRect;
		g.setColor(RThemeColor.colorSet.textColor);
		if (slider.getOrientation() == JSlider.HORIZONTAL)
		{
			g.translate(0, tickBounds.y);
			if (slider.getMinorTickSpacing() > 0)
			{
				int value = slider.getMinimum();
				while (value <= slider.getMaximum())
				{
					int xPos = xPositionForValue(value);
					paintMinorTickForHorizSlider(g, tickBounds, xPos);
					if (Integer.MAX_VALUE
							- slider.getMinorTickSpacing() < value)
						break;
					value += slider.getMinorTickSpacing();
				}
			}

			if (slider.getMajorTickSpacing() > 0)
			{
				int value = slider.getMinimum();
				while (value <= slider.getMaximum())
				{
					int xPos = xPositionForValue(value);
					paintMajorTickForHorizSlider(g, tickBounds, xPos);
					if (Integer.MAX_VALUE
							- slider.getMajorTickSpacing() < value)
						break;
					value += slider.getMajorTickSpacing();
				}
			}
			g.translate(0, -tickBounds.y);
		} else
		{
			g.translate(tickBounds.x, 0);
			if (slider.getMinorTickSpacing() > 0)
			{
				int offset = 0;
				if (!ComponentTools.isLeftToRight(slider))
				{
					offset = tickBounds.width - tickBounds.width / 2;
					g.translate(offset, 0);
				}
				int value = slider.getMinimum();
				while (value <= slider.getMaximum())
				{
					int yPos = yPositionForValue(value);
					paintMinorTickForVertSlider(g, tickBounds, yPos);
					if (Integer.MAX_VALUE
							- slider.getMinorTickSpacing() < value)
						break;
					value += slider.getMinorTickSpacing();
				}
				if (!ComponentTools.isLeftToRight(slider))
					g.translate(-offset, 0);
			}

			if (slider.getMajorTickSpacing() > 0)
			{
				if (!ComponentTools.isLeftToRight(slider))
					g.translate(2, 0);
				int value = slider.getMinimum();
				while (value <= slider.getMaximum())
				{
					int yPos = yPositionForValue(value);
					paintMajorTickForVertSlider(g, tickBounds, yPos);
					if (Integer.MAX_VALUE
							- slider.getMajorTickSpacing() < value)
						break;
					value += slider.getMajorTickSpacing();
				}
				if (!ComponentTools.isLeftToRight(slider))
					g.translate(-2, 0);
			}
			g.translate(-tickBounds.x, 0);
		}
	}

	@Override
	protected Dimension getThumbSize()
	{
		Dimension size = super.getThumbSize();
		if ((RIconFactory.getThumbIcon() != null))
		{
			size.width = RIconFactory.getThumbIcon().getIconWidth();
			size.height = RIconFactory.getThumbIcon().getIconHeight();
		}
		return size;
	}

	@Override
	public void paintThumb(Graphics g)
	{
		Icon icon;
		if ((isDragging()) && slider.isEnabled())
		{
			icon = RIconFactory.getThumbRolloverIcon();
		} else
		{
			icon = RIconFactory.getThumbIcon();
		}
		icon.paintIcon(null, g, thumbRect.x, thumbRect.y);
	}
}
